//蓝桥杯-蛇形填数
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  int i=0,j=0;
  int flag=1;//1-->斜向下走  0-->斜向上走
  
  for(int n=1;n<10000;n++)
  {
    if(i==19&&j==19)
    {
      printf("%d",n);
      break;
    }
    if(j%2==0&&i==0)
    {
      j++;
      flag=1;
    }
    else if(j==0&&i%2==1)
    {
      i++;
      flag=0;
    }
    else
    {
      if(flag)
      {
        i++,j--;
      }
      else
      {
        i--,j++;
      }
    }
  }
  return 0;
}



//蓝桥杯-跑步锻炼
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  int arr[12]={31,28,31,30,31,30,31,31,30,31,30,31};
  int year[]={12,12,12,12,12,
              12,12,12,12,12,
              12,12,12,12,12,
              12,12,12,12,12,9};
  int weekday=6;
  int c=0;
  for(int i=0;i<21;i++)
  {
    //2020+i 年
    if(i%4==0)
    {
      arr[1]=29;
    }
    else
      arr[1]=28;
    for(int index=0;index<year[i];index++)
    {
      //index+1 月
      for(int day=1;day<=arr[index];day++)
      {
        // day 号
        if(weekday==1)
        {
          c+=2;
        }
        else if(day==1)
        {
          c+=2;
        }
        else
        {
          c+=1;
        }
        weekday=weekday+1;
        if(weekday==8)
        weekday=1;
      }
    }
  }
  printf("%d",c+2);
  return 0;
}


//蓝桥杯-回文日期
#include <stdio.h>
#include <stdlib.h>

int fun(int i)
{
  int arr[12]={31,28,31,30,31 , 30,31,31,30,31 ,30,31};
  int month=(i/100)%100;

  if(month==0||month>12)
  {
    return 0;
  }
  int day=i%100;
  if(day>arr[month-1])
  return 0;
  return 1;

}
int fun1(int n)
{
  int tmp=n;
  int re=0;
  while(n)
  {
    re=re*10+n%10;
    n/=10;
  }
  return re==tmp;

}
int fun2(int n)
{
  if(!fun1(n))
  return 0;
  int arr[8]={0};
  int i=0;
  while(n)
  {
    arr[i++]=n%10;
    n/=10;
  }
  if(arr[0]==arr[2]&&arr[2]==arr[5]&&arr[5]==arr[7]&&
  arr[1]==arr[3]&&arr[3]==arr[4]&&arr[4]==arr[6])
  {
    return 1;
  }
  return 0;
}


int main(int argc, char *argv[])
{

  int n=0;
  scanf("%d",&n);
  for(int i=n+1;;i++)
  {
    if(fun(i))
    {
      if(fun1(i))
      {
        printf("%d\n",i);
        break;
      }
    }
    
  }
  for(int i=n+1;;i++)
  {
    if(fun(i))
    {
      if(fun2(i))
      {
        printf("%d\n",i);
        break;
      }
    }
  }
  return 0;
}


//蓝桥杯-杨辉三角
#include <stdio.h>
#include <stdlib.h>
int n;
int max(int a,int b)
 {
   if(a>b) return a;
   else return b;
 }
long long int fact(int a,int b)
{
  long long int x=1;
   for(int i=a,j=1;j<=b;i--,j++)
   {
     x=x*i/j;
     if(x>n) return x;
   }
   return x;
}
 int find(int k)
 {
   long long int l=2*k,r=max(n,l);
   long long int c;
   while(l<r)
   {
     int mid=(l+r)/2;
     if(fact(mid,k)>=n) r=mid;
     else l=mid+1;
   }
   if(fact(r,k)!=n) 
   {
       return 0;
   }
   else 
   {
     c=(r*(r+1))/2+k+1;
     printf("%lld",c);
     return 1;
   }
 }

int main()
{
  // 请在此输入您的代码
  scanf("%d",&n);
  for(int i=16; ;i--)
  {
    if(find(i)) break;
  }
  return 0;
}

//蓝桥杯-货物摆放
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  // long long n=2021041820210418;
  // long c=0;
  // long long k=0,s=0;
  // for(long long  i=1;i*i*i<=n;i++)
  // {
  //   if(n%i!=0)
  //   {
  //     continue;
  //   }
  //   s=n/i;
  //   for(long long j=i;i*j*j<=n;j++)
  //   {

  //     if(s%(j)==0)
  //     {
  //       k=n/(i*j);
  //       if(i==j&&j==k)
  //       {
  //         c+=1;
  //       }else if(i==j||j==k||i==k)
  //       {
  //         c+=3;
  //       }
  //       else
  //       {
  //         c+=6;
  //       }
  //     }
      
  //   }
  // }
  printf("%ld",2430);
  return 0;
}


//四数之和

int comp(const void* a, const void* b) {
    return *(int*)a - *(int*)b;
}

int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes) {
    int** quadruplets = malloc(sizeof(int*) * 1001);
    *returnSize = 0;
    *returnColumnSizes = malloc(sizeof(int) * 1001);
    if (numsSize < 4) {
        return quadruplets;
    }
    qsort(nums, numsSize, sizeof(int), comp);
    int length = numsSize;
    for (int i = 0; i < length - 3; i++) {
        if (i > 0 && nums[i] == nums[i - 1]) {
            continue;
        }
        if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
            break;
        }
        if ((long) nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) {
            continue;
        }
        for (int j = i + 1; j < length - 2; j++) {
            if (j > i + 1 && nums[j] == nums[j - 1]) {
                continue;
            }
            if ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {
                break;
            }
            if ((long) nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) {
                continue;
            }
            int left = j + 1, right = length - 1;
            while (left < right) {
                long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
                if (sum == target) {
                    int* tmp = malloc(sizeof(int) * 4);
                    tmp[0] = nums[i], tmp[1] = nums[j], tmp[2] = nums[left], tmp[3] = nums[right];
                    (*returnColumnSizes)[(*returnSize)] = 4;
                    quadruplets[(*returnSize)++] = tmp;
                    while (left < right && nums[left] == nums[left + 1]) {
                        left++;
                    }
                    left++;
                    while (left < right && nums[right] == nums[right - 1]) {
                        right--;
                    }
                    right--;
                } else if (sum < target) {
                    left++;
                } else {
                    right--;
                }
            }
        }
    }
    return quadruplets;
}



//蓝桥杯-砍竹子
#include "stdio.h"
#include "stdlib.h"
#include "math.h"

int main()
{
  int i,n;
  long long*h;
  scanf("%d",&n);
  h=(long long*)malloc(sizeof(long long)*n);
  long long arr[n][10];
  int index[n];

  for( i=0;i<n;i++){
		for(int j=0;j<6;j++){
      
			arr[i][j]=0;
		}
  }

  long long c=0;
  for(i=0;i<n;i++)
  {
    scanf("%lld",&h[i]);
    index[i]=0;
    while(h[i]>1)
    {
      arr[i][index[i]++]=h[i];
      h[i]=sqrt(h[i]/2+1);
      c++;
    }
    for(int j=index[i]-1,k=0;j>k;j--,k++)
    {
      int tmp=arr[i][j];
      arr[i][j]=arr[i][k];
      arr[i][k]=tmp;
    }
  }

  //printf("%lld",c);  
  
  for( i=1;i<n;i++){
		for(int j=0;j<6;j++){
			if(arr[i][j] && arr[i][j]==arr[i-1][j]){
				c--;
			}
		}
  }


  printf("%lld",c);  
  return 0;
}

//动态规划-博弈
bool stoneGame(int* piles, int pilesSize) {
    int dp[pilesSize];
    for (int i = 0; i < pilesSize; i++) {
        dp[i] = piles[i];
    }
    for (int i = pilesSize - 2; i >= 0; i--) {
        for (int j = i + 1; j < pilesSize; j++) {
            dp[j] = fmax(piles[i] - dp[j], piles[j] - dp[j - 1]);
        }
    }
    return dp[pilesSize - 1] > 0;
}

//MIN游戏博弈转移
boolean canWinNim(int n) {
        if (n <= 3) {
            return true;
        }
        boolean[][] dp = new boolean[2][n + 1];
        dp[0][1] = true;
        dp[0][2] = true;
        dp[0][3] = true;
        dp[1][1] = false;
        dp[1][2] = false;
        dp[1][3] = false;
        for (int i = 4; i <= n; i++) {
            if (dp[1][i - 1] || dp[1][i - 2] || dp[1][i - 3]) {
                dp[0][i] = true;
                dp[1][i] = false;
            } else {
                dp[0][i] = false;
                dp[1][i] = true;
            }
        }
        return dp[0][n];
        // return canWin(n);
    }

//从根到叶的二进制数之和

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


int dfs(struct TreeNode *root, int val) {
    if (root == NULL) {
        return 0;
    }
    val = (val << 1) | root->val;
    if (root->left == NULL && root->right == NULL) {
        return val;
    }
    return dfs(root->left, val) + dfs(root->right, val);
}

int sumRootToLeaf(struct TreeNode* root){
    return dfs(root, 0);
}


//最小路径和
int minPathSum(int** grid, int gridSize, int* gridColSize) {
    int rows = gridSize, columns = gridColSize[0];
    if (rows == 0 || columns == 0) {
        return 0;
    }
    int dp[rows][columns];
    dp[0][0] = grid[0][0];
    for (int i = 1; i < rows; i++) {
        dp[i][0] = dp[i - 1][0] + grid[i][0];
    }
    for (int j = 1; j < columns; j++) {
        dp[0][j] = dp[0][j - 1] + grid[0][j];
    }
    for (int i = 1; i < rows; i++) {
        for (int j = 1; j < columns; j++) {
            dp[i][j] = fmin(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
        }
    }
    return dp[rows - 1][columns - 1];
}



//动态规划-不同路径
int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridSize,
                             int* obstacleGridColSize) {
    int n = obstacleGridSize, m = obstacleGridColSize[0];
    int f[m];
    memset(f, 0, sizeof(f));
    f[0] = (obstacleGrid[0][0] == 0);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (obstacleGrid[i][j] == 1) {
                f[j] = 0;
                continue;
            }
            if (j - 1 >= 0 && obstacleGrid[i][j - 1] == 0) {
                f[j] += f[j - 1];
            }
        }
    }

    return f[m - 1];
}



//不同路径数
int uniquePaths(int m, int n) {
    //动态创建一个二维路径答案表
    int **dp = (int **)malloc(sizeof(int *) * n);
    for (int i = 0; i < n; i++) {
        dp[i] = (int *)malloc(sizeof(int) * m);
    }
    
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (i == 0 || j == 0) {     //最上一行或者最左一列
                dp[i][j] = 1;
            }
            else {
                dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }
        }
    }
    
    return dp[n-1][m-1];
}




//递归回溯求解，注意减枝   
#define MAX_SIZE 1430
void generate(int left, int right, int n, char *str, int index, char **result, int *returnSize) {
  if (left == n && right == n) {  //左右括号都用完
    result[(*returnSize)] =  (char*)calloc((2 * n + 1), sizeof(char));
    strcpy(result[(*returnSize)++], str);
    return;
  }

  if (left < n) {  //当左括号没用完时
    str[index] = '(';
    generate(left + 1, right, n, str, index + 1, result, returnSize);
  }
  if (left > right && right < n) {  //右括号数量必须小于左括号，否则一定不合法，且右括号没有用完
    str[index] = ')';
    generate(left, right + 1, n, str, index + 1, result, returnSize);
  }
}

char **generateParenthesis(int n, int *returnSize) {
  char *str = (char*)calloc((2 * n + 1), sizeof(char));
  char **result = (char **)malloc(sizeof(char *) * MAX_SIZE);
  *returnSize = 0;
  generate(0, 0, n, str, 0, result, returnSize);
  return result;
}



//正则表达式匹配
bool isMatch(char * s, char * p){
    int dp[strlen(s)+1][strlen(p)+1];
    //s的前i个字符   p的前j个字符
    dp[0][0]=1;
    // p为空，s不为空，必为false
    for(int i=1;i<strlen(s)+1;i++)
    {
        dp[i][0]=0;
    }
    //s为空 p非空 
    for(int j=1;j<strlen(p)+1;j++)
    {
        if(j>1&&p[j-1]=='*')
        {
            dp[0][j]=dp[0][j-2];
        }
        else
        {
            dp[0][j]=0;
        }
    }
    //s、p非空 
    for(int i=1;i<strlen(s)+1;i++)
    {
        for(int j=1;j<strlen(p)+1;j++)
        {
            //可以匹配
            if(s[i-1]==p[j-1]||p[j-1]=='.')
            {
                dp[i][j]=dp[i-1][j-1];
            }
            // 模式串末位是*
            else if (p[j - 1] == '*')
             { 
                // 模式串*的前一个字符能够跟文本串的末位匹配上
                if (s[i - 1] == p[j - 2] || p[j - 2] == '.') 
                {
                    dp[i][j] = dp[i][j - 2]      // *匹配0次的情况
                            || dp[i - 1][j];     // *匹配1次或多次的情况
                } 
                else 
                { 
                    // 模式串*的前一个字符不能够跟文本串的末位匹配
                    dp[i][j] = dp[i][j - 2];     // *只能匹配0次
                }
            }
            else
            {
                dp[i][j]=0;
            }
        }
    }
    return dp[strlen(s)][strlen(p)];

}


//最长回文子串-动态规划
	string longestPalindrome(string s) 
	{
		if (s.length() < 1)
		{
			return "";
		}
		int start = 0, end = 0;
		for (int i = 0; i < s.length(); i++)
		{
			int len1 = expandAroundCenter(s, i, i);//一个元素为中心
			int len2 = expandAroundCenter(s, i, i + 1);//两个元素为中心
			int len = max(len1, len2);
			if (len > end - start)
			{
				start = i - (len - 1) / 2;
				end = i + len / 2;
			}
		}
		return s.substr(start, end - start + 1);
	}

	int expandAroundCenter(string s, int left, int right)
	{
		int L = left, R = right;
		while (L >= 0 && R < s.length() && s[L] == s[R])
		{// 计算以left和right为中心的回文串长度
			L--;
			R++;
		}
		return R - L - 1;
	}



//将所有数字用字符替换
char * replaceDigits(char * s){
    int i=0;
    while(1){
        if(s[i]==NULL||s[i+1]==NULL) break;
        s[i+1]=('a'+(s[i]-'a'+s[i+1]+4)%26);
        i+=2;
    }
    return s;
}


//链表相加
程序分为两个部分：
1. 翻转链表
2. 进位相加
	取值（由于当指针为空不允许value域作加减运算，且要依据空指针作为结束循环条件，所以这么用）
	进位加法
	赋值（分配链接新节点）

最麻烦的就是指针越界问题，希望随着经验增加，可以快速解决吧。
纠结变量用的有点多，C语言编写，寻求改进办法，请指教！
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */
struct ListNode* convertLinkList( struct ListNode *L){
    //翻转链表
    if ( L->next == NULL )
        return L;
    struct ListNode *pre, *cur, *next;
    pre = L; cur = pre->next; next = cur->next;
    pre->next = NULL;
    
    while( cur !=NULL )
    {
        cur->next = pre;
        pre = cur; cur = next; 
        if ( next != NULL )
            next = next->next;
    }
    return pre;
}
/**
 * 
 * @param head1 ListNode类 
 * @param head2 ListNode类 
 * @return ListNode类
 */
struct ListNode* addInList(struct ListNode* head1, struct ListNode* head2 ) {
    // write code here
    struct ListNode *p, *q;
    struct ListNode  *res;
    struct ListNode  *m,*n;
    int value = 0;
    int pre = 0;
    int v1, v2;
    
    p = convertLinkList(head1);
    q = convertLinkList(head2);
    //“1”分配一个头节点，如果不先分配，只是空指针在程序下面语句 “2”处，将报错无法执行 
    m = res = (struct ListNode *)malloc( sizeof( struct ListNode) );
    m->next = NULL;
    
    while ( p || q || pre == 1)
    {
    //
        if( p != NULL )
        {
            v1 = p->val;
            p = p->next;
        }
        else v1 = 0;
        if( q != NULL )
        {
            v2 = q->val;
            q = q->next;
        }
        else v2 = 0;
        
        value = v1 +v2 + pre;
        if ( value >= 10 )
        {
            pre = 1;
            value  = value % 10;
        }
        else pre = 0;
        
        n = (struct ListNode *)malloc( sizeof( struct ListNode) );
        n->val = value;
        n->next = NULL;
        m->next = n;//-------------------"2"
        m = n;
    }
    //这里因为上面实现分配了一个空节点，所以避免返回空节点而返回第二个开始，并翻转一次，得到正确结果。
    return convertLinkList(res->next);
}


//句子相似性 III
#define MIN(a, b) ((a) < (b) ? (a) : (b))

bool areSentencesSimilar(char * sentence1, char * sentence2) {
    int len1 = strlen(sentence1), len2 = strlen(sentence2);
    char *words1[len1], *words2[len2];
    int words1Size = 0, words2Size = 0;
    char *p = strtok(sentence1, " ");
    while (p != NULL) {
        words1[words1Size++] = p;
        p = strtok(NULL, " ");
    }
    p = strtok(sentence2, " ");
    while (p != NULL) {
        words2[words2Size++] = p;
        p = strtok(NULL, " ");
    }
    int i = 0, j = 0;
    while (i < words1Size && i < words2Size && strcmp(words1[i], words2[i]) == 0) {
        i++;
    }
    while (j < words1Size - i && j < words2Size - i && strcmp(words1[words1Size - j - 1], words2[words2Size - j - 1]) == 0) {
        j++;
    }
    return i + j == MIN(words1Size, words2Size);
}

//有界数组中指定下标处的最大值
long cal(int i,int len)
{
    // i-1 i-2           i-(len)
    // 3 2 1
    if(i-1 >len)
    {
        return (long)(i-1+i-len)*len/2;
    }
    // i-1 i-2         1  
    else
    {
        return (long)(i-1+1)*(i-1)/2+(len-i+1);
    }
}
bool valid(int i, int n, int index, int maxSum)
{
        long long sum=0;
        sum+=i;
        sum+=cal(i,index);
        sum+=cal(i,n-1-index);
        return sum<=maxSum;
}
int maxValue(int n, int index, int maxSum){    
    int maxi=maxSum;
    int mini=1;
    int i=0;
    while(mini<maxi)
    {
        i=(mini+maxi+1)/2;
        //下标  0       1 2 3    4      ……     index index+1  …… n-1
        //值 i-(index-0)        i-(index-4)      i    i-1      
        if(valid(i, n, index, maxSum))
        {
            mini=i;
        }
        else
        {
            maxi=i-1;
        }
    }    
    return mini;
    
}

//贪心与二分
long cal(int big, int length) {
    if (length + 1 < big) {
        int small = big - length;
        return (long) (big - 1 + small) * length / 2;
    } else {
        int ones = length - (big - 1);
        return (long) big * (big - 1) / 2 + ones;
    }
}

bool valid(int mid, int n, int index, int maxSum) {
    int left = index;
    int right = n - index - 1;
    return mid + cal(mid, left) + cal(mid, right) <= maxSum;
}

int maxValue(int n, int index, int maxSum) {
    int left = 1, right = maxSum;
    while (left < right) {
        int mid = (left + right + 1) / 2;
        if (valid(mid, n, index, maxSum)) {
            left = mid;
        } else {
            right = mid - 1;
        }
    }
    return left;
}






//服创赛伪代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

#define NUMBER_L 7
#define NUMBER_D 19
int my_ceil(int x, int y) {
	if (x % y == 0)
	{
		return x / y;
	}
	else
		return x / y + 1;
}
int* Adjust(int arr[5][26], int require_work_num[26], int* returnsize) {

	/*  breaktime_record[200]  -->  12   13   34
	两个数字为一组，前一个代表三角形里的编号 后一个代表7-12 里的编号（0-5）*/
	int* breaktime_record = (int*)calloc(500, 4);
	if (breaktime_record == NULL)
	{
		exit(1);
	}
	int breaktime_record_index = 0;
	//时间跨度：午饭3小时，晚饭3小时
	//午饭三角形人数
	int sum1 = 0;
	sum1 = arr[3][NUMBER_L - 1]
		+ arr[4][NUMBER_L - 1] + arr[4][NUMBER_L - 2];
	//晚饭三角形人数
	int sum2 = 0;
	sum2 = arr[3][NUMBER_D - 1]
		+ arr[4][NUMBER_D - 1] + arr[4][NUMBER_D - 2];
	//1.没有需要处理的
	if (sum1 == 0 && sum2 == 0)
	{
		*returnsize = 0;
		return   breaktime_record;
	}
	//2.处理午饭
	if (sum1)
	{
		int real_work_num = 0;
		int surplus_record[6] = { 0 };
		//用这个数组进行记录存在冗余的人数
		//计算7~12时共有多少人
		int index = 0;
		for (int i = 6; i < 12; i++)
		{
			//第i时  j控制行号   i为每行要加的最右边数字下标
			real_work_num = 0;
			for (int j = 0; j < 5; j++)
			{
				for (int k = 0; k < j + 4; k++)
				{
					if (i - k >= 0)
						real_work_num += arr[j][i - k];
				}

			}
			//没有冗余
			if (real_work_num == require_work_num[i])
			{
				continue;
			}
			//存在冗余
			else
			{
				surplus_record[index] = real_work_num - require_work_num[i];
			}
			index++;
		}

		/*  surplus_record 记录了7-12 的冗余人数*/
		//开始记录

		//1.arrange_num[]  记录三角形内的需要安排休息的人数  
		/*  映射关系
		* 三角形：（每多1行元素相应增加1）
		*        0
		*     1
		*  3  4  5
		*6 7  8  9
		* ……
		*
		* 0 -->arr下标  【3,6】
		* 1  2 -->         【4,5】【4,6】
		*
		*/
		int arrange_num[3] = { 0 };
		arrange_num[0] = arr[3][NUMBER_L - 1];
		arrange_num[1] = arr[4][NUMBER_L - 2];
		arrange_num[2] = arr[4][NUMBER_L - 1];

		//对arrange_num数组和surplus_record数组处理就行

		//1.冗余处理并记录
		//遍历surplus_record数组
		for (int i = 0; i < 6; i++)
		{
			//i--> 时间编号，有冗余
			if (surplus_record[i] != 0)
			{
				while (surplus_record[i])
				{
					int j = 0;
					while (j < 3 && arrange_num[j] == 0)
					{
						j++;
					}
					//全部处理完了
					if (j == 3)
					{
						break;
					}
					//j--> 三角形的编号
					breaktime_record[breaktime_record_index++] = j;
					breaktime_record[breaktime_record_index++] = i;
					arrange_num[j]--;
					sum1--;
					surplus_record[i]--;
				}
			}
		}

		//2.增派人手
		int addnum = my_ceil(sum1, 6);
		arr[3][NUMBER_L - 1] += addnum;

		//3.记录增派人手后要岔开吃饭的人
		if (addnum)
		{
			int time_index = 0;
			for (int i = 0; i < 3; i++)
			{
				if (arrange_num[i] != 0)
				{
					while (arrange_num[i]--)
					{
						breaktime_record[breaktime_record_index++] = i;
						breaktime_record[breaktime_record_index++] = time_index;
						time_index = (++time_index) % 5;
					}
				}
			}
		}

	}
	//3.处理晚饭
	if (sum2)
	{
		int real_work_num = 0;
		int surplus_record[6] = { 0 };
		//用这个数组进行记录存在冗余的人数
		//计算19~25时共有多少人
		int index = 0;
		for (int i = 6; i < 12; i++)
		{
			//第i时  j控制行号   i为每行要加的最右边数字下标
			real_work_num = 0;
			for (int j = 0; j < 5; j++)
			{
				for (int k = 0; k < j + 4; k++)
				{
					if (i - k >= 0)
						real_work_num += arr[j][i - k];
				}

			}
			//没有冗余
			if (real_work_num == require_work_num[i])
			{
				continue;
			}
			//存在冗余
			else
			{
				surplus_record[index] = real_work_num - require_work_num[i];
			}
			index++;
		}

		/*  surplus_record 记录了19-25 的冗余人数*/
		//开始记录

		//1.arrange_num[]  记录三角形内的需要安排休息的人数  
		/*  映射关系
		* 三角形：（每多1行元素相应增加1）
		*        0
		*     1
		*  3  4  5
		*6 7  8  9
		* ……
		*
		* 0 -->arr下标  【3,6】
		* 1  2 -->         【4,5】【4,6】
		*
		*/
		int arrange_num[3] = { 0 };
		arrange_num[0] = arr[3][NUMBER_L - 1];
		arrange_num[1] = arr[4][NUMBER_L - 2];
		arrange_num[2] = arr[4][NUMBER_L - 1];

		//对arrange_num数组和surplus_record数组处理就行

		//1.冗余处理并记录
		//遍历surplus_record数组
		for (int i = 0; i < 6; i++)
		{
			//i--> 时间编号，有冗余
			if (surplus_record[i] != 0)
			{
				while (surplus_record[i])
				{
					int j = 0;
					while (j < 3 && arrange_num[j] == 0)
					{
						j++;
					}
					//全部处理完了
					if (j == 3)
					{
						break;
					}
					//j--> 三角形的编号
					breaktime_record[breaktime_record_index++] = j;
					breaktime_record[breaktime_record_index++] = i;
					arrange_num[j]--;
					sum2--;
					surplus_record[i]--;
				}
			}
		}

		//2.增派人手
		int addnum = my_ceil(sum2, 6);
		arr[3][NUMBER_D- 1] += addnum;

		//3.记录增派人手后要岔开吃饭的人
		if (addnum)
		{
			int time_index = 0;
			for (int i = 0; i < 3; i++)
			{
				if (arrange_num[i] != 0)
				{
					while (arrange_num[i]--)
					{
						breaktime_record[breaktime_record_index++] = i;
						breaktime_record[breaktime_record_index++] = time_index;
						time_index = (++time_index) % 5;
					}
				}
			}
		}

	}

	*returnsize = breaktime_record_index;
	return breaktime_record;
}
int main() {
	//假设当天是周一
	//定义二维数组
	int a[5][26] = { 0 };
	a[0][12] = 3;
	a[0][22] = 1;
	a[1][0] = 1;
	a[1][4] = 1;
	a[1][8] = 4;
	a[1][12] = 1;
	a[1][19] = 4;
	a[1][21] = 2;
	a[2][3] = 2;
	a[2][7] = 1;
	a[2][12] = 1;
	a[3][3] = 1;
	a[3][7] = 1;
	a[3][19] = 8;
	a[4][12] = 2;


	a[3][18] = 1;
	a[4][18] = 3;
	a[4][17] = 1;



	int num[26] = { 1,1,1,4,5,2,4,6,10,7,8,7,12,6,1,3,2,1,5,10,8,2,11,9,5,14 };

	int* p = NULL;
	int size = 0;
	p = Adjust(a, num, &size);
	printf("%d\n", size);
	for (int i = 0; i < size; i += 2)
	{
		printf("%d %d\n", p[i], p[i + 1]);
	}

	return 0;
}



#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

#define NUMBER_L 7
#define NUMBER_D 7
void Adjust(int arr[5][26],int num[26]) {
	//时间跨度：午饭3小时，晚饭3小时
	//午饭三角形人数
	int sum1 = 0;
	sum1 = arr[3][NUMBER_L]
		+ arr[4][NUMBER_L] + arr[4][NUMBER_L - 1];
	//晚饭三角形人数
	int sum2 = 0;
	sum2 = arr[3][NUMBER_D]
		+ arr[4][NUMBER_D] + arr[4][NUMBER_D - 1];
	//1.没有需要处理的
	if (sum1 == 0 && sum2 == 0)
		return;
	//2.处理午饭
	if (sum1)
	{
		int sum = 0;
		//计算7~12时共有多少人
		for (int i = 7; i < 13; i++)
		{
			//第i时  j控制行号
			for (int j = 0; j < 5; j++)
			{
				for (int k = i; k < i - j + 1; k--)
				{
					sum += arr[i][j];
				}
			}
			//没有冗余
			if (sum == num[i])
			{
				continue;
			}
			else
			{
				//sum1-=（sum-num[i]），sum1就是该剩下需要处理的人

				//可以提供（sum-num[i]）人干饭

				//记录下，一/2/3圈  （sum-num[i]）  在 i时干饭

			}
		}
		//sum1就是该剩下需要处理的人
		//addnum=sum1/6
		//记录下，一/2/3圈  里多的人  分别在 7-12岔开干饭
		//arr[2][6]+=addnum
		//最后需要的就是arr 和记录的表



	}
	//3.处理晚饭
	if (sum2)
	{

	}
		

}
int main() {
	//假设当天是周一
	//定义二维数组
	int a[5][26] = { 0 };

	return 0;
}





// 括号的最大嵌套深度
#define MAX(a, b) ((a) > (b) ? (a) : (b))

int maxDepth(char * s){
    int ans = 0, size = 0;
    int n = strlen(s);
    for (int i = 0; i < n; ++i) {
        if (s[i] == '(') {
            ++size;
            ans = MAX(ans, size);
        } else if (s[i] == ')') {
            --size;
        }
    }
    return ans;
}


//整理字符串
char * makeGood(char * s){
    int i = 0, j;
    for (j = 1; j < strlen(s); j ++) {
        if ( i == -1 || (s[i] != s[j] - 32  &&  s[i] != s[j] + 32) ) {
            s[++ i] = s[j];
        } else {
            i --;
        }
    }
    s[++ i] = '\0';
    return s;
}

//搜索插入位置
int searchInsert(int* nums, int numsSize, int target) {
    int left = 0, right = numsSize - 1, ans = numsSize;
    while (left <= right) {
        int mid = ((right - left) >> 1) + left;
        if (target <= nums[mid]) {
            ans = mid;
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return ans;
}

//链表加数
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
    int tem_now = 0, tem_last = 0;  //tem_now 用于计算当前两个节点的两个数相加是否进位
                                    //tem_last用于保存前一节点的进位
    struct ListNode* head = l1;     
    struct ListNode* pre=NULL;      //pre表示运行到空的前一节点
    if(l1 == NULL)                  //当初始情况有一节点为空时，直接输出另一链表
        return l2;
    if(l2 == NULL)
        return l1;
    while(l1 != NULL || l2 != NULL){    //循环条件，某一链表非空
        if(l1 == NULL){                 //当l1空时
            pre -> next = l2;           //将l2拼接到l1的后面
            pre = pre -> next;
            tem_now = (pre -> val + tem_last) / 10; //将尾节点再次计算，防止发生进位
            pre -> val = (pre -> val +tem_last) % 10;
            tem_last = tem_now;
            break;                      //结束循环，处理剩余节点
        }else if(l2 == NULL){           //同上
            pre = pre -> next;
            tem_now = (pre -> val + tem_last) / 10;
            pre -> val = (pre -> val + tem_last) % 10;
            tem_last = tem_now;
            break;
        }else{                  //li和l2都非空的情况，比较常规，不解释
            tem_now = (l1 -> val + l2 -> val + tem_last) / 10;
            l1 -> val = (l1 -> val + l2 -> val + tem_last) % 10;
            pre = l1;
            l1 = l1 -> next;
            l2 = l2 -> next;
            tem_last = tem_now;
        }
    }
    while(pre -> next != NULL){ //当pre并未在最后一个节点时，计算进位，并向后遍历，直到下一个节点为空
        pre = pre -> next;
        tem_now = (pre -> val + tem_last) / 10;
        pre -> val = (pre -> val + tem_last) % 10;
        tem_last = tem_now;
    }
    if(tem_last > 0){           //如果前一节点进位仍大于0，创建一个节点，拼接在链表后
        struct ListNode* node = malloc(sizeof(struct ListNode));
        node -> val = tem_last;
        node -> next = NULL;
        pre -> next = node;
    }
    return head;
}

//句子排序-字符串操作
char * sortSentence(char * s){
    int n=strlen(s);//后面再求会变化
    char* ret[10]={0};
    char* r=(char*)calloc(strlen(s)+1,1);
    
    char* tmp=&s[0];
    for(int i=0;i<n;i++)
    {
        if(s[i]==' ')
        {
            s[i]='\0';
            tmp=&s[i+1];
        }
        else if(isdigit(s[i]))
        {
            ret[s[i]-'0']=tmp;
            s[i]=' ';
        }
    }
    int i=0;
    for( i=1;i<10;i++)
    {
        if(ret[i]!=NULL)
        {
            strcat(r,ret[i]);
        }
        else
            break;
    }
    r[n-i+1]='\0';
    return r;
}

//二分法搜索插入位置
int searchInsert(int* nums, int numsSize, int target){
    int left = 0, right = numsSize - 1, ans = numsSize;
    while (left <= right) {
        int mid = ((right - left) >> 1) + left;
        if (target <= nums[mid]) {
            ans = mid;
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return ans;


}
/*
int searchInsert(int* nums, int numsSize, int target){
    int left=0,right=numsSize-1;
    //printf("%d %d\n",left,right);
    while(right-left>1)
    {
        int mid=(right-left)/2+left;
        if(nums[mid]>target)
            right=mid-1;            
        else if(nums[mid]<target)
            left=mid+1;     
        else
            return mid;
    }
    if(left>right)
    {
        int tmp=left;
        left=right;
        right=left;
    }   
    if(target>nums[right])
        return right+1;
    else if(target==nums[right]||target>nums[left])
        return right;
    else
        return left;
    
    return 0;

}*/

//判断一个链表是否为回文结构
bool isPail(struct ListNode* head ) {
    // write code here
    if(head==NULL || head->next==NULL)
    return true;
    
    struct ListNode *p=head,*q,*head2;
    head2=(struct ListNode*)malloc(sizeof(struct ListNode));
    head2->next=NULL;
    while(p!=NULL)
    {
        q=(struct ListNode*)malloc(sizeof(struct ListNode));
        q->val=p->val;
        q->next=head2->next;
        head2->next=q;
        p=p->next;
    }
    p=head;
    while(p!=NULL)
    {
        if(p->val!=q->val)
            return false;
        p=p->next;
        q=q->next;
    }
   
    return true;
}
//链表的奇偶重排
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static，防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定，请勿修改，直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @return ListNode类
 */
struct ListNode* oddEvenList(struct ListNode* head ) {
    // write code
    if(head==NULL || head->next==NULL || head->next->next==NULL)
    {
        return head;
    }
    struct ListNode* p0;  
    struct ListNode* p1;  
    struct ListNode* p2;  
    struct ListNode* p3;
    struct ListNode* phead;
    

    phead = head->next;
    p2 = head;
    p3 = head->next;
    while(p3->next!=NULL && p3!=NULL)
    {
        p0 = p2;
        p2 = p3->next;
        p1 = p3;
        p3 = p2->next;
        p0->next = p2;
        p2->next = phead;
        p1->next = p3;
    }
    return head;
    
    
    
}


//二进制一的个数
 int count = 0;
        while (n != 0) {
            ++count;
            n = (n - 1) & n;
        }
        return count;

 int count = 0;
        int flag = 1;
        while (flag != 0) {
            if ((n & flag) != 0) {
                count++;
            }
            flag = flag << 1;
        }
        return count;

//颠倒二进制位
uint32_t reverseBits(uint32_t n) {
    uint32_t rev = 0;
    for (int i = 0; i < 32 && n > 0; ++i) {
        rev |= (n & 1) << (31 - i);
        n >>= 1;
    }
    return rev;
}


//单调递增的数字
void itoa(int num, char* str, int* strSize) {
    *strSize = 0;
    while (num > 0) {
        str[(*strSize)++] = num % 10 + '0';
        num /= 10;
    }
    for (int i = 0; i < (*strSize) / 2; i++) {
        int tmp = str[i];
        str[i] = str[(*strSize) - 1 - i];
        str[(*strSize) - 1 - i] = tmp;
    }
}

int monotoneIncreasingDigits(int n) {
    int strNSize;
    char strN[11];
    itoa(n, strN, &strNSize);
    int i = 1;
    while (i < strNSize && strN[i - 1] <= strN[i]) {
        i += 1;
    }
    if (i < strNSize) {
        while (i > 0 && strN[i - 1] > strN[i]) {
            strN[i - 1] -= 1;
            i -= 1;
        }
        for (i += 1; i < strNSize; ++i) {
            strN[i] = '9';
        }
    }
    return atoi(strN);
}

// 寻找数组的中心下标
int pivotIndex(int* nums, int numsSize) {
    int total = 0;
    for (int i = 0; i < numsSize; ++i) {
        total += nums[i];
    }
    int sum = 0;
    for (int i = 0; i < numsSize; ++i) {
        if (2 * sum + nums[i] == total) {
            return i;
        }
        sum += nums[i];
    }
    return -1;
}

作者：力扣官方题解
链接：https://leetcode.cn/problems/find-pivot-index/solutions/579264/xun-zhao-shu-zu-de-zhong-xin-suo-yin-by-gzjle/
来源：力扣（LeetCode）
著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
int pivotIndex(int* nums, int numsSize) {
    int total = 0;
    for (int i = 0; i < numsSize; ++i) {
        total += nums[i];
    }
    int sum = 0;
    for (int i = 0; i < numsSize; ++i) {
        if (2 * sum + nums[i] == total) {
            return i;
        }
        sum += nums[i];
    }
    return -1;
}

//汇总区间
char** summaryRanges(int* nums, int numsSize, int* returnSize) {
    char** ret = malloc(sizeof(char*) * numsSize);
    *returnSize = 0;
    int i = 0;
    while (i < numsSize) {
        int low = i;
        i++;
        while (i < numsSize && nums[i] == nums[i - 1] + 1) {
            i++;
        }
        int high = i - 1;
        char* temp = malloc(sizeof(char) * 25);
        sprintf(temp, "%d", nums[low]);
        if (low < high) {
            sprintf(temp + strlen(temp), "->");
            sprintf(temp + strlen(temp), "%d", nums[high]);
        }
        ret[(*returnSize)++] = temp;
    }
    return ret;
}
//四数之和
int comp(const void* a, const void* b) {
    return *(int*)a - *(int*)b;
}

int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes) {
    int** quadruplets = malloc(sizeof(int*) * 1001);
    *returnSize = 0;
    *returnColumnSizes = malloc(sizeof(int) * 1001);
    if (numsSize < 4) {
        return quadruplets;
    }
    qsort(nums, numsSize, sizeof(int), comp);
    int length = numsSize;
    for (int i = 0; i < length - 3; i++) {
        if (i > 0 && nums[i] == nums[i - 1]) {
            continue;
        }
        if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
            break;
        }
        if ((long) nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) {
            continue;
        }
        for (int j = i + 1; j < length - 2; j++) {
            if (j > i + 1 && nums[j] == nums[j - 1]) {
                continue;
            }
            if ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {
                break;
            }
            if ((long) nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) {
                continue;
            }
            int left = j + 1, right = length - 1;
            while (left < right) {
                long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
                if (sum == target) {
                    int* tmp = malloc(sizeof(int) * 4);
                    tmp[0] = nums[i], tmp[1] = nums[j], tmp[2] = nums[left], tmp[3] = nums[right];
                    (*returnColumnSizes)[(*returnSize)] = 4;
                    quadruplets[(*returnSize)++] = tmp;
                    while (left < right && nums[left] == nums[left + 1]) {
                        left++;
                    }
                    left++;
                    while (left < right && nums[right] == nums[right - 1]) {
                        right--;
                    }
                    right--;
                } else if (sum < target) {
                    left++;
                } else {
                    right--;
                }
            }
        }
    }
    return quadruplets;
}
//买卖股票的最佳时机
int maxProfit(int* prices, int pricesSize){
    int max=0,min=prices[0];
    int i;
    for(i=0;i<pricesSize;i++){
            if(prices[i]<min)
                min=prices[i];
            else if(prices[i]-min>max)
                    max=prices[i]-min;
        }
    return max;
}

//填充每个节点的下一个右侧节点指针
struct Node* connect(struct Node* root) {
    if (root == NULL) {
        return root;
    }

    // 初始化队列同时将第一层节点加入队列中，即根节点
    struct Node* Q[5000];
    int left = 0, right = 0;
    Q[right++] = root;

    // 外层的 while 循环迭代的是层数
    while (left < right) {
        // 记录当前队列大小
        int size = right - left;

        // 遍历这一层的所有节点
        for (int i = 0; i < size; i++) {
            // 从队首取出元素
            struct Node* node = Q[left++];

            // 连接
            if (i < size - 1) {
                node->next = Q[left];
            }

            // 拓展下一层节点
            if (node->left != NULL) {
                Q[right++] = node->left;
            }
            if (node->right != NULL) {
                Q[right++] = node->right;
            }
        }
    }

    // 返回根节点
    return root;
}


//二叉树坡度
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int dfs(struct TreeNode* root){
    if(root==NULL){
        return 0;
    }
    return root->val+dfs(root->left)+dfs(root->right);
}
int findTilt(struct TreeNode* root){
    if(root==NULL)
        return 0;
    else
        return fabs(dfs(root->left)-dfs(root->right))+findTilt(root->left)+findTilt(root->right);
}

//合并区间
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

int Cmp(const int** a, const int** b){
    return *a[0] > *b[0];
}

int** merge(int** intervals, int intervalsSize, int* intervalsColSize, int* returnSize, int** returnColumnSizes){
    
    (*returnSize) = 0;                                        //无论如何都会输出至少一个区间
    *returnColumnSizes = malloc(sizeof(int) * intervalsSize);
    (*returnColumnSizes)[*returnSize] = 2;
    (*returnSize)++;
    
    if(intervalsSize == 1)               //如果只有一个一个区间，直接返回
    {   
        return intervals;
    }

    qsort(intervals, intervalsSize, sizeof(int)*2, Cmp);  //以每个区间的第一个值为标准，进行快排

    int max = intervals[intervalsSize-1][1]+1;    //当两个区间合并后，改变后面区间的第一个值为最大值+1

    int left = 0;                     //双指针
    int right = 1;
    while(right < intervalsSize)      
    {
        if(intervals[left][1] >= intervals[right][0])     //两个区间有交集
        {
            intervals[left][1] = intervals[left][1] > intervals[right][1] ? intervals[left][1]  :intervals[right][1];   //改变left节点的第二个值

            intervals[right][0] = max;    //改变节点的第一个值

            right++;                      //后面节点+1
        }
        else   //如果没有交集
        {
            (*returnColumnSizes)[*returnSize] = 2; 
            (*returnSize)++;

            left = right;         //left指向right
            right++;              //right+1
        }
    }

    //最后再进行一个快速排序(max值在这发挥作用)
    qsort(intervals, intervalsSize, sizeof(int) * 2, Cmp);
    
    return intervals;
}

最好结果:
![image.png](https://pic.leetcode.cn/1667390015-yqklYt-image.png)

//二叉搜索树中的搜索
struct TreeNode* dfs(struct TreeNode* root, int val)
{
    //DFS 结束条件
    if (root == NULL)
    {
        return NULL;
    }

    //执行条件
    if (root->val == val)
    {
        return root;
    }

    struct TreeNode* node;
    //下次遍历条件
    //因为是二叉搜索树 所以是有序的
    if ( val < root->val )
    {
        node = dfs(root->left, val);
    }
    else
    {
        node = dfs(root->right, val);
    }
    return node;
}




void dfs(char* s, int n, int i, int** f, char*** ret, int* retSize, int* retColSize, char** ans, int* ansSize) {
    if (i == n) {
        char** tmp = malloc(sizeof(char*) * (*ansSize));
        for (int j = 0; j < (*ansSize); j++) {
            int ansColSize = strlen(ans[j]);
            tmp[j] = malloc(sizeof(char) * (ansColSize + 1));
            strcpy(tmp[j], ans[j]);
        }
        ret[*retSize] = tmp;
        retColSize[(*retSize)++] = *ansSize;
        return;
    }
    for (int j = i; j < n; ++j) {
        if (f[i][j]) {
            char* sub = malloc(sizeof(char) * (j - i + 2));
            for (int k = i; k <= j; k++) {
                sub[k - i] = s[k];
            }
            sub[j - i + 1] = '\0';
            ans[(*ansSize)++] = sub;
            dfs(s, n, j + 1, f, ret, retSize, retColSize, ans, ansSize);
            --(*ansSize);
        }
    }
}
//分割回文串
char*** partition(char* s, int* returnSize, int** returnColumnSizes) {
    int n = strlen(s);
    int retMaxLen = n * (1 << n);
    char*** ret = malloc(sizeof(char**) * retMaxLen);
    *returnSize = 0;
    *returnColumnSizes = malloc(sizeof(int) * retMaxLen);
    int* f[n];
    for (int i = 0; i < n; i++) {
        f[i] = malloc(sizeof(int) * n);
        for (int j = 0; j < n; j++) {
            f[i][j] = 1;
        }
    }
    for (int i = n - 1; i >= 0; --i) {
        for (int j = i + 1; j < n; ++j) {
            f[i][j] = (s[i] == s[j]) && f[i + 1][j - 1];
        }
    }
    char* ans[n];
    int ansSize = 0;
    dfs(s, n, 0, f, ret, returnSize, *returnColumnSizes, ans, &ansSize);
    return ret;
}

struct TreeNode* searchBST(struct TreeNode* root, int val) 
{
    return dfs(root, val);
}

//最大子数组和
int maxSubArray(int* nums, int numsSize){
    
    int arr[numsSize];
    int max=nums[0];
    for(int i=0;i<numsSize;i++)
    {
        if(max>=0&&nums[i]<0)
            continue;
        if(nums[i]>max)
            max=nums[i];
        arr[i]=nums[i];
        for(int j=i+1;j<numsSize;j++)
        {
            arr[j]=arr[j-1]+nums[j];
            if(arr[j]>max)
                max=arr[j];
        }
    }
    return max;

}